import numpy as np
from scipy import linalg


# calculate frechet inception distance
def calculate_fid(act1, act2):
    """
    https://blog.csdn.net/jackzhang11/article/details/104995524
    FID表示的是生成图像的特征向量与真实图像的特征向量之间的距离，该距离越近，表明生成模型的效果越好，即图像的清晰度高，且多样性丰富。
    FID Frechet Inception Distance（FID）
    """
    # calculate mean and covariance statistics
    mu1, sigma1 = act1.mean(axis=0), np.cov(act1, rowvar=False)
    mu2, sigma2 = act2.mean(axis=0), np.cov(act2, rowvar=False)
    # calculate sum squared difference between means
    ssdiff = np.sum((mu1 - mu2) ** 2.0)
    # calculate sqrt of product between cov
    covmean = linalg.sqrtm(sigma1.dot(sigma2))
    # check and correct imaginary numbers from sqrt
    if np.iscomplexobj(covmean):
        covmean = covmean.real
    # calculate score
    fid = ssdiff + np.trace(sigma1 + sigma2 - 2.0 * covmean)
    return fid
